home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Commodities / WindowShuffle / WindowShuffle.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  25KB  |  776 lines

  1. /*
  2.  *  WindowShuffle.c
  3.  *
  4.  *  Commodity
  5.  *
  6.  *  Author: Stefan Sticht
  7.  *
  8.  *  Copyright: source is public domain, no copyright
  9.  *
  10.  *  Version history:
  11.  *
  12.  *  V1.00   initial release
  13.  *  V1.02   recompiled with main.c V1.02
  14.  *  V1.03   completly rewritten; shared commodity code thrown away; smaller, uses less CPU time
  15.  *  V1.04   now refuses to activate windows specified with REFUSE
  16.  *          second pair of hotkeys for only Activate without WindowToFront()
  17.  *          changed Priority to 21 to block out intuition for safety reasons
  18.  *  V1.05   some really minor changes
  19.  *  V1.06   recompiled with changed (for 68040 compatiblity) cback.o
  20.  *          removed error when started from WB: taskpri wasn't set to 21
  21.  *          thanks to Uwe Röhm
  22.  *  V1.07   small changes, moved UnlockIBase() in processmessages()
  23.  *  V1.08   Changes by Andreas M. Kirchitz, see README.amk:
  24.  *          new option SETMOUSE,
  25.  *          changed break handling to work with SAS/C 6
  26.  */
  27.  
  28. #define VERSION "1.08"
  29.  
  30. /********************************************************************
  31.  *                             interfacing                          *
  32.  ********************************************************************/
  33.  
  34. /*
  35.  *  include files
  36.  */
  37.  
  38. #include <stdarg.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <intuition/intuitionbase.h>
  42. #include <libraries/commodities.h>
  43.  
  44. #include <clib/alib_protos.h>
  45. #include <clib/commodities_protos.h>
  46. #include <pragmas/commodities_pragmas.h>
  47. #include <clib/dos_protos.h>
  48. #include <pragmas/dos_pragmas.h>
  49. #include <clib/exec_protos.h>
  50. #include <pragmas/exec_pragmas.h>
  51. #include <clib/intuition_protos.h>
  52. #include <pragmas/intuition_pragmas.h>
  53.  
  54. /* AMK: input.device stuff */
  55. #include <exec/types.h>
  56. #include <exec/memory.h>
  57. #include <devices/input.h>
  58. #include <devices/inputevent.h>
  59. #include <intuition/screens.h>
  60. /* AMK: input.device stuff */
  61.  
  62. #ifdef DEBUG
  63. #define printf KPrintF
  64. #include <clib/dlib_protos.h>
  65. #endif
  66.  
  67. /*
  68.  *  prototypes
  69.  */
  70. long request(char *title, char *gadgets, char *text, ...);
  71. struct Library *myopenlibrary(char *name, unsigned long version);
  72. struct Window *lastwindow(struct Window *win);
  73. struct Window *nextwindow(struct Window *win);
  74. struct Window *prevwindow(struct Window *win);
  75. void *retryallocmem(unsigned long size, long mode);
  76. void processmessages(void);
  77.  
  78. /* AMK: set mouse pointer */
  79. void setnewmousepos(struct Window *win);
  80. /* AMK: set mouse pointer */
  81.  
  82. /*
  83.  *  global data defined in other moduls
  84.  *
  85.  *  libraries opened by startup code; basepointers needed by function pragmas
  86.  */
  87. extern struct Library *DOSBase;
  88. extern struct Library *SysBase;
  89.  
  90. /*
  91.  *  Disable SAS/C CTRL/C handling
  92.  */
  93. void chkabort(void) {}
  94.  
  95. /* AMK: SAS/C 6.x */
  96. #ifdef __SASC
  97. __regargs int _CXBRK(void) { return(0); }  /* Disable Lattice CTRL/C handling */
  98. __regargs int __chkabort(void) { return(0); }  /* really */
  99. #endif
  100. /* AMK: SAS/C 6.x */
  101.  
  102. /********************************************************************
  103.  *                             global data                          *
  104.  ********************************************************************/
  105.  
  106. #define TT_PREVAC  "PREV_ACTIVE"
  107. #define TT_NEXTAC  "NEXT_ACTIVE"
  108. #define TT_PREVBO  "PREV_BOTH"
  109. #define TT_NEXTBO  "NEXT_BOTH"
  110.  
  111. /*
  112.  *  definition of all messages (multi language support not completed yet)
  113.  */
  114. #ifdef GERMAN
  115.  
  116. #define RETRY_GADGETS           "Wiederholen|Abbrechen"
  117. #define RESUME_GADGETS          "Weiter"
  118. #define MSG_OUTOFMEM            "Leider ein Speicherblock von %ld bytes\nnicht alloziert werden!"
  119. #define MSG_LIBRARY_OPENERR     "Die %s (V%ld+) kann nicht geöffnet werden!"
  120. #define COM_NAME                "Fensterln"
  121. #define COM_DESCR               "Nächstes/letztes Fenster aktivieren"
  122. #define TT_BACKDROP             "BACKDROP"
  123. #define TT_NOWINTITLE           "OHNETITEL"
  124. #define TT_REFUSE               "DIESENICHT"
  125. /* AMK: set mouse pointer */
  126. #define TT_SETMOUSE             "SETZEMAUS"
  127. /* AMK: set mouse pointer */
  128. #define MSG_REFUSE_TOO_COMPLEX  "Leider muß " TT_REFUSE " ignoriert werden,\nda der Ausdruck zu komplex ist."
  129. #define NO                      "NEIN"
  130. #define YES                     "JA"
  131.  
  132. #else
  133.  
  134. #define RETRY_GADGETS           "Retry|Cancel"
  135. #define RESUME_GADGETS          "Resume"
  136. #define MSG_OUTOFMEM            "Failure allocting %ld bytes of memory!"
  137. #define MSG_LIBRARY_OPENERR     "%s (V%ld+) can't be opened!"
  138. #define COM_NAME                "WindowShuffle"
  139. #define COM_DESCR               "Activate next/previous window"
  140. #define TT_BACKDROP             "BACKDROP"
  141. #define TT_NOWINTITLE           "WITHOUTTITLE"
  142. #define TT_REFUSE               "REFUSE"
  143. /* AMK: set mouse pointer */
  144. #define TT_SETMOUSE             "SETMOUSE"
  145. /* AMK: set mouse pointer */
  146. #define MSG_REFUSE_TOO_COMPLEX  TT_REFUSE " will be ignored\nas the pattern is too complex!"
  147. #define YES                     "YES"
  148. #define NO                      "NO"
  149.  
  150. #endif
  151.  
  152. #define COM_TITLE           COM_NAME " " VERSION
  153. #define CX_PRIORITY         "CX_PRIORITY"
  154. #define DEF_CX_PRIORITY     0
  155.  
  156. #define DEF_TT_PREVAC       "lcommand lshift j"
  157. #define DEF_TT_NEXTAC       "lcommand lshift k"
  158. #define DEF_TT_PREVBO       "lcommand j"
  159. #define DEF_TT_NEXTBO       "lcommand k"
  160. #define DEF_TT_BACKDROP     NO
  161. #define DEF_TT_NOWINTITLE   NO
  162. #define DEF_TT_REFUSE       ""
  163. /* AMK: set mouse pointer */
  164. #define DEF_TT_SETMOUSE     NO
  165. /* AMK: set mouse pointer */
  166.  
  167. /*
  168.  *  data for cback.o
  169.  */
  170. long _stack = 4096l;
  171. char *_procname = COM_NAME;
  172. #define PRIORITY 21l
  173. long _priority = PRIORITY;
  174. long _BackGroundIO = 1;
  175. extern BPTR _Backstdout;
  176.  
  177. /*
  178.  *  library base pointers
  179.  */
  180. struct IntuitionBase *IntuitionBase;
  181. struct Library *CxBase;
  182. struct Library *IconBase;
  183.  
  184. /*
  185.  *  message port
  186.  */
  187. struct MsgPort *cxport = NULL;
  188.  
  189. /*
  190.  *  signal flag
  191.  */
  192. unsigned long cxsigflag = 0l;
  193.  
  194. /*
  195.  *  programtitle and version for Version command
  196.  */
  197. char versionstring[] ="\0$VER: " COM_NAME " " VERSION;
  198.  
  199. /*
  200.  *  helpstring
  201.  */
  202. #ifdef GERMAN
  203. char helpstring[] =
  204. "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) von Stefan Sticht\n"\
  205. "Aufruf: " COM_NAME " ["\
  206. CX_PRIORITY "=<Zahl>] [" TT_NEXTAC "=<Zeichenkette>] [" TT_PREVAC "=<Zeichenkette>] ["\
  207. TT_NEXTBO "=<Zeichenkette>] [" TT_PREVBO "=<Zeichenkette>] [" TT_BACKDROP "=" YES "|" NO "] ["\
  208. TT_NOWINTITLE "=" YES "|" NO "] [" TT_SETMOUSE "=" YES "|" NO "] [" TT_REFUSE "=<Zeichenkette>]\n";
  209. #else
  210. char helpstring[] =
  211. "\033[1m" COM_NAME "\033[0m " VERSION " (Public Domain) by Stefan Sticht\n"
  212. "Usage: " COM_NAME " ["\
  213. CX_PRIORITY "=<number>] [" TT_NEXTAC "=<string>] [" TT_PREVAC "=<string>] ["\
  214. TT_NEXTBO "=<string>] [" TT_PREVBO "=<string>] [" TT_BACKDROP "=" YES "|" NO "] ["\
  215. TT_NOWINTITLE "=" YES "|" NO "] [" TT_SETMOUSE "=" YES "|" NO "] [" TT_REFUSE "=<string>]\n";
  216. #endif
  217.  
  218. /*
  219.  *  the tooltypearray
  220.  */
  221. char **tooltypes;
  222.  
  223. /*
  224.  *  our broker
  225.  */
  226. CxObj *broker = NULL;
  227.  
  228. struct NewBroker newbroker = {
  229.     NB_VERSION,                         /* BYTE nb_Version               */
  230.     COM_NAME,                           /* BYTE *nb_Name                 */
  231.     COM_TITLE,                          /* BYTE *nb_Title                */
  232.     COM_DESCR,                          /* BYTE *nb_Descr                */
  233.     NBU_NOTIFY | NBU_UNIQUE,            /* SHORT nb_Unique               */
  234.     0,                                  /* SHORT nb_Flags                */
  235.     0,                                  /* BYTE nb_Pri                   */
  236.     NULL,                               /* struct MsgPort nb_Port        */
  237.     0                                   /* WORD nb_ReservedChannel       */
  238. };
  239.  
  240. #define NEXTAC  1
  241. #define PREVAC  2
  242. #define NEXTBO  3
  243. #define PREVBO  4
  244.  
  245. /*
  246.  *  pointer to refuse tokens
  247.  */
  248. char *refusetokens = NULL;
  249. /*
  250.  *  booleans for activation of backdrop windows and windows w/o title
  251.  */
  252. unsigned short backdrop;
  253. unsigned short nowintitle;
  254. unsigned short setmouse;
  255.  
  256. /********************************************************************
  257.  *                             functions                            *
  258.  ********************************************************************/
  259.  
  260. /*
  261.  *  request(): a glue routine to EasyRequest as simple as printf plus
  262.  *             titlestring, gadgettexts
  263.  *
  264.  *  Input: char *title:         pointer to the title of the requester
  265.  *         char *gadgets:       pointer to gadgettext
  266.  *         char *text:          text displayed in requester
  267.  *
  268.  *  Result: same as EasyrequestArgs()
  269.  *
  270.  * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
  271.  */
  272. long request(char *title, char *gadgets, char *text, ...)
  273. {
  274.     /*
  275.      *  structure textreq only needed in this function, so hide it here
  276.      *  must be static, in order to be initialized only once
  277.      */
  278.     static struct EasyStruct textreq = {
  279.         sizeof (struct EasyStruct), /* ULONG es_StructSize      */
  280.         0l,                         /* ULONG es_Flags           */
  281.         NULL,                       /* UBYTE *es_Title          */
  282.         NULL,                       /* UBYTE *es_TextFormat     */
  283.         NULL,                       /* UBYTE *es_GadgetFormat   */
  284.         };
  285.     va_list ap;
  286.     long rc;
  287.  
  288.     /*
  289.      *  get start of variable arguments
  290.      */
  291.     va_start(ap, text);
  292.  
  293.     /*
  294.      *  update textreq
  295.      */
  296.     textreq.es_Title = (UBYTE *)title;
  297.     textreq.es_TextFormat = (UBYTE *)text;
  298.     textreq.es_GadgetFormat = (UBYTE *)gadgets;
  299.  
  300.     /*
  301.      *  win may be NULL
  302.      */
  303.     rc = EasyRequestArgs(NULL, &textreq, NULL, ap);
  304.  
  305.     va_end(ap);
  306.  
  307.     return(rc);
  308. }
  309.  
  310. /*
  311.  *  myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
  312.  *                   if OpenLibrary() fails, to give the user a chance to
  313.  *                   copy the library to libs: and retry
  314.  *                   requires request(), see above
  315.  */
  316. struct Library *myopenlibrary(char *name, unsigned long version)
  317. {
  318.     static char errortext[] = MSG_LIBRARY_OPENERR;
  319.     struct Library *libptr;
  320.     long ok = TRUE;
  321.  
  322.     do {
  323.         if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
  324.             if (IntuitionBase) ok = request(COM_NAME ":", RETRY_GADGETS, errortext, name, version);
  325.             else ok = FALSE;
  326.             }
  327.         } while (!libptr && ok);
  328.  
  329.     #ifdef DEBUG
  330.     printf("myopenlibrary(%s, %ld) = 0x%lx\n", name, version, libptr);
  331.     #endif
  332.     return(libptr);
  333. }
  334.  
  335. void *retryallocmem(unsigned long size, long mode)
  336. {
  337.     void *addr;
  338.  
  339.     do {
  340.  
  341.         if (!(addr = AllocMem(size, mode))) {
  342.             if (!(request(COM_NAME ":", RETRY_GADGETS, MSG_OUTOFMEM, size))) return(NULL);
  343.             }
  344.  
  345.         } while (!addr);
  346.  
  347.     return(addr);
  348. }
  349.  
  350. void main(int argc, char *argv[])
  351. {
  352.     CxObj *nextacfilter = NULL;
  353.     CxObj *prevacfilter = NULL;
  354.     CxObj *nextbofilter = NULL;
  355.     CxObj *prevbofilter = NULL;
  356.     struct Message *msg;
  357.     char *refuse;
  358.     char *nextackey;
  359.     char *prevackey;
  360.     char *nextbokey;
  361.     char *prevbokey;
  362.     unsigned long size = 0l;
  363.  
  364.     if ((argc > 1) && (*argv[1] == '?')) {
  365.         /*
  366.          *  display help string
  367.          */
  368.         if (_Backstdout) {
  369.             Write(_Backstdout, helpstring, sizeof(helpstring) - 1l);
  370.             Close(_Backstdout);
  371.             }
  372.         return;
  373.         }
  374.     else if (argc && _Backstdout) Close(_Backstdout);
  375.     else if (!argc) {
  376.         /*
  377.          *  started from Workbench: cback.o doesn't change our priority,
  378.          *  so we do here
  379.          */
  380.         struct Task *mytask;
  381.         if (mytask = FindTask(NULL)) SetTaskPri(mytask, PRIORITY);
  382.         }
  383.  
  384.     /*
  385.      *  open required libraries first
  386.      */
  387.     if (IntuitionBase = (struct IntuitionBase *)myopenlibrary("intuition.library", 37l)) {
  388.  
  389.         if (CxBase = myopenlibrary("commodities.library", 37l)) {
  390.  
  391.             if (IconBase = myopenlibrary("icon.library", 37l)) {
  392.  
  393.                 /*
  394.                  * create tooltypes array (requires icon.library open!!!)
  395.                  */
  396.                 tooltypes = (char **)ArgArrayInit(argc, argv);
  397.  
  398.                 /*
  399.                  *  create our message port
  400.                  */
  401.                 if (cxport = CreateMsgPort()) {
  402.  
  403.                     cxsigflag = 1l << cxport->mp_SigBit;
  404.                     /*
  405.                      * set up some broker data
  406.                      */
  407.                     newbroker.nb_Pri = ArgInt(tooltypes, CX_PRIORITY, DEF_CX_PRIORITY);
  408.                     newbroker.nb_Port = cxport;
  409.  
  410.                     if (broker = CxBroker(&newbroker, NULL)) {
  411.  
  412.                         if ((nextackey = ArgString(tooltypes, TT_NEXTAC, DEF_TT_NEXTAC)) &&
  413.                             *nextackey) {
  414.  
  415.                             if (nextacfilter = HotKey(nextackey, cxport, NEXTAC))
  416.                                 AttachCxObj(broker, nextacfilter);
  417.  
  418.                             } /* if nextackey */
  419.  
  420.                         if ((prevackey = ArgString(tooltypes, TT_PREVAC, DEF_TT_PREVAC)) &&
  421.                             *prevackey) {
  422.  
  423.                             if (prevacfilter = HotKey(prevackey, cxport, PREVAC))
  424.                                 AttachCxObj(broker, prevacfilter);
  425.  
  426.                             } /* if prevackey */
  427.  
  428.                         if ((nextbokey = ArgString(tooltypes, TT_NEXTBO, DEF_TT_NEXTBO)) &&
  429.                             *nextbokey) {
  430.  
  431.                             if (nextbofilter = HotKey(nextbokey, cxport, NEXTBO))
  432.                                 AttachCxObj(broker, nextbofilter);
  433.  
  434.                             } /* if nextbokey */
  435.  
  436.                         if ((prevbokey = ArgString(tooltypes, TT_PREVBO, DEF_TT_PREVBO)) &&
  437.                             *prevbokey) {
  438.  
  439.                             if (prevbofilter = HotKey(prevbokey, cxport, PREVBO))
  440.                                 AttachCxObj(broker, prevbofilter);
  441.  
  442.                             } /* if prevbokey */
  443.  
  444.                         backdrop = (strcmpi((char *)ArgString(tooltypes, TT_BACKDROP, DEF_TT_BACKDROP),
  445.                                     YES)) ? FALSE : TRUE;
  446.  
  447.                         nowintitle = (strcmpi((char *)ArgString(tooltypes, TT_NOWINTITLE, DEF_TT_NOWINTITLE),
  448.                                     YES)) ? FALSE : TRUE;
  449.  
  450.                         refuse = (char *)ArgString(tooltypes, TT_REFUSE, DEF_TT_REFUSE);
  451.  
  452.                         /* AMK: set mouse pointer */
  453.                         setmouse = (strcmpi((char *)ArgString(tooltypes, TT_SETMOUSE, DEF_TT_SETMOUSE),
  454.                                     YES)) ? FALSE : TRUE;
  455.                         /* AMK: set mouse pointer */
  456.  
  457.                         #ifdef DEBUG
  458.                         if (refuse) printf("WindowShuffle: refuse = %s\n", refuse);
  459.                         #endif
  460.  
  461.                         if (*refuse && (size = (strlen(refuse) << 1)) &&
  462.                             (refusetokens = retryallocmem(size, 0l))) {
  463.  
  464.                             #ifdef DEBUG
  465.                             printf("WindowShuffle: size = %ld, refusetokens = 0x%lx\n", size, refusetokens);
  466.                             #endif
  467.  
  468.                             if (ParsePattern(refuse, refusetokens, size) == -1l)
  469.                                 request(COM_NAME ":", RESUME_GADGETS, MSG_REFUSE_TOO_COMPLEX);
  470.  
  471.                             #ifdef DEBUG
  472.                             printf("WindowShuffle: refusetokens = %s\n", refusetokens);
  473.                             #endif
  474.  
  475.                             }
  476.  
  477.                         if ((nextacfilter && !CxObjError(nextacfilter)) ||
  478.                             (prevacfilter && !CxObjError(prevacfilter)) ||
  479.                             (nextbofilter && !CxObjError(nextbofilter)) ||
  480.                             (prevbofilter && !CxObjError(prevbofilter))) {
  481.                             /*
  482.                              *  activate our commodity
  483.                              */
  484.                             ActivateCxObj(broker, 1l);
  485.                             /*
  486.                              *  now watch our numerous ports
  487.                              */
  488.                             processmessages();
  489.  
  490.                             } /* if !CxObjError() */
  491.  
  492.                         DeleteCxObjAll(broker);
  493.  
  494.                         if (refusetokens) FreeMem(refusetokens, size);
  495.  
  496.                         } /* if broker */
  497.  
  498.                     #ifdef DEBUG
  499.                     else printf("main(): CxBroker() failed!\n");
  500.                     #endif
  501.  
  502.                     /*
  503.                      *  delete our message port after replying all pending messages
  504.                      */
  505.                     while (msg = GetMsg(cxport)) ReplyMsg(msg);
  506.                     DeleteMsgPort(cxport);
  507.                     } /* if cxport */
  508.  
  509.                 #ifdef DEBUG
  510.                 else printf("main(): CraeteMsgPort() failed!\n");
  511.                 #endif
  512.  
  513.                 ArgArrayDone();
  514.  
  515.                 CloseLibrary(IconBase);
  516.                 } /* if IconBase */
  517.  
  518.             CloseLibrary(CxBase);
  519.             } /* if CxBase */
  520.  
  521.     CloseLibrary((struct Library *)IntuitionBase);
  522.     } /* if IntuitionBase */
  523.  
  524. } /* main() */
  525.  
  526. #define PREV    1
  527. #define TOF     2
  528. #define AC      4
  529. #define BO      6
  530.  
  531. void processmessages(void)
  532. {
  533.     struct Window *win;
  534.     struct Message *msg;
  535.     unsigned long sigreceived;
  536.     unsigned long msgtype;
  537.     unsigned long msgid;
  538.     unsigned long lock;
  539.     unsigned short quit = FALSE;
  540.     unsigned char mode;
  541.  
  542.     while (!quit) {
  543.  
  544.         sigreceived = Wait(SIGBREAKF_CTRL_C | cxsigflag);
  545.  
  546.         #ifdef DEBUG
  547.         printf("processmessages(): signal received\n");
  548.         #endif
  549.  
  550.         if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE;
  551.  
  552.         if (sigreceived & cxsigflag) {
  553.  
  554.             while (msg = (struct Message *)GetMsg(cxport)) {
  555.  
  556.                 msgid = CxMsgID((CxMsg *)msg);
  557.                 msgtype = CxMsgType((CxMsg *)msg);
  558.  
  559.                 ReplyMsg(msg);
  560.  
  561.                 switch (msgtype) {
  562.  
  563.                     case CXM_IEVENT:
  564.                         mode = 0;
  565.                         switch (msgid) {
  566.  
  567.                             case PREVAC:    mode = PREV;
  568.                             case NEXTAC:    mode |= AC;
  569.                                             break;
  570.  
  571.                             case PREVBO:    mode = PREV;
  572.                             case NEXTBO:    mode |= BO;
  573.                                             break;
  574.  
  575.                             } /* switch msgid */
  576.  
  577.                         lock = LockIBase(0l);
  578.                         if (mode & PREV) {
  579.                             /*
  580.                              *  get previous window
  581.                              */
  582.                             if (!(win = prevwindow(IntuitionBase->ActiveWindow))) {
  583.                                 /*
  584.                                  *  no prev window; get last window;
  585.                                  *  if last window = backdrop || nowintitle ||
  586.                                  *  refusewindow get predecessor of lastwindow
  587.                                  */
  588.                                 if ((win = lastwindow(IntuitionBase->ActiveWindow)) &&
  589.                                     ((!backdrop && (win->Flags & WFLG_BACKDROP)) ||
  590.                                     (!nowintitle && !win->Title)) ||
  591.                                     (refusetokens && win->Title && MatchPattern(refusetokens, win->Title)))
  592.                                     win = prevwindow(win);
  593.                                     }
  594.                             }
  595.                         else {
  596.                             /*
  597.                              *  get next window
  598.                              */
  599.                             if (!(win = nextwindow(IntuitionBase->ActiveWindow))) {
  600.                                 /*
  601.                                  *  no next window; get first window;
  602.                                  *  if first window = backdrop || nowintitle ||
  603.                                  *  refusewindow get first window->NextWindow
  604.                                  */
  605.                                 if ((win = IntuitionBase->ActiveScreen->FirstWindow) &&
  606.                                     ((!backdrop && (win->Flags & WFLG_BACKDROP)) ||
  607.                                     (!nowintitle && !win->Title)) ||
  608.                                     (refusetokens && win->Title && MatchPattern(refusetokens, win->Title)))
  609.                                     win = nextwindow(win);
  610.                                 }
  611.                             }
  612.  
  613.                         /*
  614.                          *  now activate and windowtofront the window if (win != NULL)
  615.                          */
  616.                         if (win) {
  617.  
  618.                             if ((mode & AC) && (win != IntuitionBase->ActiveWindow))
  619.                                 ActivateWindow(win);
  620.                             if ((mode & TOF) && (!(win->Flags & WFLG_BACKDROP)))
  621.                                 WindowToFront(win);
  622.                             }
  623.  
  624.                         UnlockIBase(lock);
  625.  
  626.                         /* AMK: set mouse pos, does not work while IBase is locked */
  627.                         if (win && setmouse) setnewmousepos(win);
  628.                         /* AMK: set mouse pos, does not work while IBase is locked */
  629.  
  630.                         break;
  631.  
  632.                     case CXM_COMMAND:
  633.                         switch (msgid) {
  634.  
  635.                             case CXCMD_UNIQUE:
  636.                             case CXCMD_KILL:
  637.                                 quit = TRUE;
  638.                                 break;
  639.  
  640.                             case CXCMD_DISABLE:
  641.                                 ActivateCxObj(broker, 0l);
  642.                                 break;
  643.  
  644.                             case CXCMD_ENABLE:
  645.                                 ActivateCxObj(broker, 1l);
  646.                                 break;
  647.  
  648.                             }
  649.                         break;
  650.  
  651.                     } /* switch msgtype */
  652.  
  653.                 } /* while CxMsg */
  654.  
  655.             } /* if (sigreceived & cxsigflag) */
  656.  
  657.         } /* while !quit */
  658.  
  659.     ActivateCxObj(broker, 0l);
  660. }
  661.  
  662. /*
  663.  *  commodity functions
  664.  *
  665.  *  get next window
  666.  */
  667. struct Window *nextwindow(register struct Window *win)
  668. {
  669.     register struct Window *w = NULL;
  670.  
  671.     if (win) {
  672.  
  673.         while (!w && win->NextWindow) {
  674.  
  675.             w = win = win->NextWindow;
  676.  
  677.             if ((!backdrop && (w->Flags & WFLG_BACKDROP)) ||
  678.                 (!nowintitle && !w->Title) ||
  679.                 (refusetokens && w->Title && MatchPattern(refusetokens, w->Title)))
  680.                 w = NULL;
  681.  
  682.             } /* while !w */
  683.  
  684.         } /* if win */
  685.  
  686.     return(w);
  687. }
  688.  
  689. /*
  690.  *  get previous window
  691.  */
  692. struct Window *prevwindow(register struct Window *win)
  693. {
  694.     register struct Window *w = NULL;
  695.  
  696.     if (win) {
  697.  
  698.         while (!w && (win != win->WScreen->FirstWindow)) {
  699.  
  700.             for (w = win->WScreen->FirstWindow; w->NextWindow != win; w = w->NextWindow);
  701.  
  702.             if ((!backdrop && (w->Flags & WFLG_BACKDROP)) ||
  703.                 (!nowintitle && !w->Title) ||
  704.                 (refusetokens && w->Title && MatchPattern(refusetokens, w->Title))) {
  705.  
  706.                 win = w;
  707.                 w = NULL;
  708.  
  709.                 }
  710.  
  711.             } /* while !w */
  712.  
  713.         } /* if win */
  714.  
  715.     return(w);
  716. }
  717.  
  718. /*
  719.  *  get last window
  720.  */
  721. struct Window *lastwindow(register struct Window *win)
  722. {
  723.     if (win) {
  724.  
  725.         while (win->NextWindow) win = win->NextWindow;
  726.  
  727.         } /* if win */
  728.  
  729.     return(win);
  730. }
  731.  
  732.  
  733.  
  734. /* AMK: set mouse pointer */
  735. /*
  736.  *  set new mouse pointer position
  737.  */
  738. void setnewmousepos(struct Window *win)
  739. {
  740.     struct IOStdReq        *InputIO;
  741.     struct MsgPort        *InputMP;
  742.     struct InputEvent    *FakeEvent;
  743.     struct IEPointerPixel    *NewPixel;
  744.  
  745.     if (InputMP=CreateMsgPort()) {
  746.         if (FakeEvent=AllocVec(sizeof(struct InputEvent),MEMF_PUBLIC|MEMF_CLEAR)) {
  747.             if (NewPixel=AllocVec(sizeof(struct IEPointerPixel),MEMF_PUBLIC|MEMF_CLEAR)) {
  748.                 if (InputIO=CreateIORequest(InputMP,sizeof(struct IOStdReq))) {
  749.                     if (!OpenDevice("input.device",NULL,(struct IORequest *)InputIO,NULL)) {
  750.                         NewPixel->iepp_Screen     = win->WScreen;
  751.                         NewPixel->iepp_Position.X = win->LeftEdge;
  752.                         NewPixel->iepp_Position.Y = win->TopEdge;
  753.                         FakeEvent->ie_EventAddress = (APTR)NewPixel;
  754.                         FakeEvent->ie_NextEvent    = NULL;
  755.                         FakeEvent->ie_Class        = IECLASS_NEWPOINTERPOS;
  756.                         FakeEvent->ie_SubClass     = IESUBCLASS_PIXEL;
  757.                         FakeEvent->ie_Code         = IECODE_NOBUTTON;
  758.                         FakeEvent->ie_Qualifier    = NULL;
  759.                         InputIO->io_Data    = (APTR)FakeEvent;
  760.                         InputIO->io_Length  = sizeof(struct InputEvent);
  761.                         InputIO->io_Command = IND_WRITEEVENT;
  762.                         DoIO((struct IORequest *)InputIO);
  763.                         CloseDevice((struct IORequest *)InputIO);
  764.                     }
  765.                     DeleteIORequest(InputIO);
  766.                 }
  767.                 FreeVec(NewPixel);
  768.             }
  769.             FreeVec(FakeEvent);
  770.         }
  771.         DeleteMsgPort(InputMP);
  772.     }
  773. }
  774. /* AMK: set mouse pointer */
  775.  
  776.